//
// Created by 谢哲 on 2021/4/18.
//

#include <iostream>
#include <vector>
#include <set>
using namespace std;


class timeSplit {
public:
    int s = 0, e = 0;

    timeSplit() = default;
    timeSplit(int s, int e): s(s), e(e) {}

    bool operator < (const timeSplit &rhs) const {
        return s < rhs.s;
    }
};


int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);

    int m, n;
    cin >> m >> n;

    vector<vector<int>> mdata(n, vector<int>(m, 0)), vdata(n, vector<int>(m, 0));
    vector<int> process_seq(m*n, 0);

    for (int i=0;i<m*n;++i) {
        cin >> process_seq[i];
        --process_seq[i];
    }

    for (int i=0;i<n;++i) {
        for (int j=0;j<m;++j) {
            cin >> mdata[i][j];
            --mdata[i][j];
        }
    }

    for (int i=0;i<n;++i) {
        for (int j=0;j<m;++j) {
            cin >> vdata[i][j];
        }
    }

    vector<set<timeSplit>> machine(m);
    vector<vector<int>> last_end_time(n, vector<int>(m, 0));
    vector<int> process_cnt(n);

    int result = 0;

    for (auto p: process_seq) {
        int cur_task = process_cnt[p];
        int cur_machine = mdata[p][cur_task];
        int cur_time = vdata[p][cur_task];
        ++process_cnt[p];

        int start_time = 0;
        if (cur_task > 0) {
            start_time = last_end_time[p][cur_task-1];
        }
        for (auto &q: machine[cur_machine]) {
            if (q.s - start_time >= cur_time) {
                break;
            }
            start_time = max(start_time, q.e);
        }

        machine[cur_machine].insert(timeSplit(start_time, start_time+cur_time));
        result = max(result, start_time+cur_time);
        last_end_time[p][cur_task] = start_time+cur_time;
    }

    cout << result;

    return 0;
}
